package com.hyts.codex.scanner.spring.bean;

import com.hyts.codex.scanner.spring.build.AnnotationCustomTypeFilterBuilder;
import com.hyts.codex.scanner.spring.scanner.SpringAnnotationCustomScanner;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * project-name:coffice-codex
 * package-name:com.hyts.codex.scanner.spring.bean
 * author:Libo/Alex
 * create-date:2019-05-18 19:07
 * copyright:libo-hyts-github
 * email:libo2dev@aliyun.com
 * description:此类主要用于: 总体定义相关的控制服务
 */
@Accessors(chain = true)
public class SpringCustomAnnotationLoader implements ApplicationContextAware, BeanFactoryPostProcessor, InitializingBean {


    /**
     * 注册服务容器
     */
    @Setter
    @Getter
    private ApplicationContext applicationContext;

    @Getter
    private SpringAnnotationCustomScanner springAnnotationCustomScanner;

    @Setter
    @Getter
    private List<String> annotationNames;

    @Setter
    @Getter
    private boolean containAnnotation;

    @Setter
    @Getter
    private boolean containInterface;

    @Setter
    @Getter
    private String basePackage;


    /**
     * 启动ConfigurableListableBeanFactory - beanFactory
     * 对象构建 - 构建 bean对象的时候进行控制 - 一切的开端
     * @param beanFactory
     * @throws BeansException
     */
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        //构建对象操作
        AnnotationCustomTypeFilterBuilder builder = AnnotationCustomTypeFilterBuilder.builder().
                annotations(annotationNames.toArray(new String[annotationNames.size()])).
                containInterface(containInterface).containMetaAnnotation(containAnnotation).build();
        this.springAnnotationCustomScanner = new SpringAnnotationCustomScanner((BeanDefinitionRegistry)beanFactory,builder.buildCustomTypeFilters());
        this.springAnnotationCustomScanner.setResourceLoader(applicationContext);
        this.springAnnotationCustomScanner.scan(StringUtils.tokenizeToStringArray(this.basePackage,
                ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS));
    }

    /**
     * 构建对象结束后进行属性赋值功能
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {

    }

    /**
     * applicationContext 对象
     * @param applicationContext
     * @throws BeansException
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}
